home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / csv.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  13KB  |  441 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. '''
  5. csv.py - read/write/investigate CSV files
  6. '''
  7. import re
  8. from _csv import Error, __version__, writer, reader, register_dialect, unregister_dialect, get_dialect, list_dialects, QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, __doc__
  9.  
  10. try:
  11.     from cStringIO import StringIO
  12. except ImportError:
  13.     from StringIO import StringIO
  14.  
  15. __all__ = [
  16.     'QUOTE_MINIMAL',
  17.     'QUOTE_ALL',
  18.     'QUOTE_NONNUMERIC',
  19.     'QUOTE_NONE',
  20.     'Error',
  21.     'Dialect',
  22.     'excel',
  23.     'excel_tab',
  24.     'reader',
  25.     'writer',
  26.     'register_dialect',
  27.     'get_dialect',
  28.     'list_dialects',
  29.     'Sniffer',
  30.     'unregister_dialect',
  31.     '__version__',
  32.     'DictReader',
  33.     'DictWriter']
  34.  
  35. class Dialect:
  36.     _name = ''
  37.     _valid = False
  38.     delimiter = None
  39.     quotechar = None
  40.     escapechar = None
  41.     doublequote = None
  42.     skipinitialspace = None
  43.     lineterminator = None
  44.     quoting = None
  45.     
  46.     def __init__(self):
  47.         if self.__class__ != Dialect:
  48.             self._valid = True
  49.         
  50.         errors = self._validate()
  51.         if errors != []:
  52.             raise Error, 'Dialect did not validate: %s' % ', '.join(errors)
  53.         
  54.  
  55.     
  56.     def _validate(self):
  57.         errors = []
  58.         if not self._valid:
  59.             errors.append("can't directly instantiate Dialect class")
  60.         
  61.         if self.delimiter is None:
  62.             errors.append('delimiter character not set')
  63.         elif not isinstance(self.delimiter, str) or len(self.delimiter) > 1:
  64.             errors.append('delimiter must be one-character string')
  65.         
  66.         if self.quotechar is None:
  67.             if self.quoting != QUOTE_NONE:
  68.                 errors.append('quotechar not set')
  69.             
  70.         elif not isinstance(self.quotechar, str) or len(self.quotechar) > 1:
  71.             errors.append('quotechar must be one-character string')
  72.         
  73.         if self.lineterminator is None:
  74.             errors.append('lineterminator not set')
  75.         elif not isinstance(self.lineterminator, str):
  76.             errors.append('lineterminator must be a string')
  77.         
  78.         if self.doublequote not in (True, False):
  79.             errors.append('doublequote parameter must be True or False')
  80.         
  81.         if self.skipinitialspace not in (True, False):
  82.             errors.append('skipinitialspace parameter must be True or False')
  83.         
  84.         if self.quoting is None:
  85.             errors.append('quoting parameter not set')
  86.         
  87.         if self.quoting is QUOTE_NONE:
  88.             if not isinstance(self.escapechar, (unicode, str)) or len(self.escapechar) > 1:
  89.                 errors.append('escapechar must be a one-character string or unicode object')
  90.             
  91.         
  92.         return errors
  93.  
  94.  
  95.  
  96. class excel(Dialect):
  97.     delimiter = ','
  98.     quotechar = '"'
  99.     doublequote = True
  100.     skipinitialspace = False
  101.     lineterminator = '\r\n'
  102.     quoting = QUOTE_MINIMAL
  103.  
  104. register_dialect('excel', excel)
  105.  
  106. class excel_tab(excel):
  107.     delimiter = '\t'
  108.  
  109. register_dialect('excel-tab', excel_tab)
  110.  
  111. class DictReader:
  112.     
  113.     def __init__(self, f, fieldnames = None, restkey = None, restval = None, dialect = 'excel', *args, **kwds):
  114.         self.fieldnames = fieldnames
  115.         self.restkey = restkey
  116.         self.restval = restval
  117.         self.reader = reader(f, dialect, *args, **kwds)
  118.  
  119.     
  120.     def __iter__(self):
  121.         return self
  122.  
  123.     
  124.     def next(self):
  125.         row = self.reader.next()
  126.         if self.fieldnames is None:
  127.             self.fieldnames = row
  128.             row = self.reader.next()
  129.         
  130.         while row == []:
  131.             row = self.reader.next()
  132.         d = dict(zip(self.fieldnames, row))
  133.         lf = len(self.fieldnames)
  134.         lr = len(row)
  135.         if lf < lr:
  136.             d[self.restkey] = row[lf:]
  137.         elif lf > lr:
  138.             for key in self.fieldnames[lr:]:
  139.                 d[key] = self.restval
  140.             
  141.         
  142.         return d
  143.  
  144.  
  145.  
  146. class DictWriter:
  147.     
  148.     def __init__(self, f, fieldnames, restval = '', extrasaction = 'raise', dialect = 'excel', *args, **kwds):
  149.         self.fieldnames = fieldnames
  150.         self.restval = restval
  151.         if extrasaction.lower() not in ('raise', 'ignore'):
  152.             raise ValueError, "extrasaction (%s) must be 'raise' or 'ignore'" % extrasaction
  153.         
  154.         self.extrasaction = extrasaction
  155.         self.writer = writer(f, dialect, *args, **kwds)
  156.  
  157.     
  158.     def _dict_to_list(self, rowdict):
  159.         if self.extrasaction == 'raise':
  160.             for k in rowdict.keys():
  161.                 if k not in self.fieldnames:
  162.                     raise ValueError, 'dict contains fields not in fieldnames'
  163.                     continue
  164.             
  165.         
  166.         return [ rowdict.get(key, self.restval) for key in self.fieldnames ]
  167.  
  168.     
  169.     def writerow(self, rowdict):
  170.         return self.writer.writerow(self._dict_to_list(rowdict))
  171.  
  172.     
  173.     def writerows(self, rowdicts):
  174.         rows = []
  175.         for rowdict in rowdicts:
  176.             rows.append(self._dict_to_list(rowdict))
  177.         
  178.         return self.writer.writerows(rows)
  179.  
  180.  
  181.  
  182. try:
  183.     complex
  184. except NameError:
  185.     complex = float
  186.  
  187.  
  188. class Sniffer:
  189.     '''
  190.     "Sniffs" the format of a CSV file (i.e. delimiter, quotechar)
  191.     Returns a Dialect object.
  192.     '''
  193.     
  194.     def __init__(self):
  195.         self.preferred = [
  196.             ',',
  197.             '\t',
  198.             ';',
  199.             ' ',
  200.             ':']
  201.  
  202.     
  203.     def sniff(self, sample, delimiters = None):
  204.         '''
  205.         Returns a dialect (or None) corresponding to the sample
  206.         '''
  207.         (quotechar, delimiter, skipinitialspace) = self._guess_quote_and_delimiter(sample, delimiters)
  208.         if delimiter is None:
  209.             (delimiter, skipinitialspace) = self._guess_delimiter(sample, delimiters)
  210.         
  211.         
  212.         class dialect(Dialect):
  213.             _name = 'sniffed'
  214.             lineterminator = '\r\n'
  215.             quoting = QUOTE_MINIMAL
  216.             doublequote = False
  217.  
  218.         dialect.delimiter = delimiter
  219.         if not quotechar:
  220.             pass
  221.         dialect.quotechar = '"'
  222.         dialect.skipinitialspace = skipinitialspace
  223.         return dialect
  224.  
  225.     
  226.     def _guess_quote_and_delimiter(self, data, delimiters):
  227.         """
  228.         Looks for text enclosed between two identical quotes
  229.         (the probable quotechar) which are preceded and followed
  230.         by the same character (the probable delimiter).
  231.         For example:
  232.                          ,'some text',
  233.         The quote with the most wins, same with the delimiter.
  234.         If there is no quotechar the delimiter can't be determined
  235.         this way.
  236.         """
  237.         matches = []
  238.         for restr in ('(?P<delim>[^\\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?P=delim)', '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?P<delim>[^\\w\n"\'])(?P<space> ?)', '(?P<delim>>[^\\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)', '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'):
  239.             regexp = re.compile(restr, re.DOTALL | re.MULTILINE)
  240.             matches = regexp.findall(data)
  241.             if matches:
  242.                 break
  243.                 continue
  244.         
  245.         if not matches:
  246.             return ('', None, 0)
  247.         
  248.         quotes = { }
  249.         delims = { }
  250.         spaces = 0
  251.         for m in matches:
  252.             n = regexp.groupindex['quote'] - 1
  253.             key = m[n]
  254.             if key:
  255.                 quotes[key] = quotes.get(key, 0) + 1
  256.             
  257.             
  258.             try:
  259.                 n = regexp.groupindex['delim'] - 1
  260.                 key = m[n]
  261.             except KeyError:
  262.                 continue
  263.  
  264.             if key:
  265.                 if delimiters is None or key in delimiters:
  266.                     delims[key] = delims.get(key, 0) + 1
  267.                 
  268.             
  269.             try:
  270.                 n = regexp.groupindex['space'] - 1
  271.             except KeyError:
  272.                 continue
  273.  
  274.             if m[n]:
  275.                 spaces += 1
  276.                 continue
  277.         
  278.         quotechar = reduce((lambda a, b, quotes = quotes: if not quotes[a] > quotes[b] or a:
  279. passb), quotes.keys())
  280.         if delims:
  281.             delim = reduce((lambda a, b, delims = delims: if not delims[a] > delims[b] or a:
  282. passb), delims.keys())
  283.             skipinitialspace = delims[delim] == spaces
  284.             if delim == '\n':
  285.                 delim = ''
  286.             
  287.         else:
  288.             delim = ''
  289.             skipinitialspace = 0
  290.         return (quotechar, delim, skipinitialspace)
  291.  
  292.     
  293.     def _guess_delimiter(self, data, delimiters):
  294.         """
  295.         The delimiter /should/ occur the same number of times on
  296.         each row. However, due to malformed data, it may not. We don't want
  297.         an all or nothing approach, so we allow for small variations in this
  298.         number.
  299.           1) build a table of the frequency of each character on every line.
  300.           2) build a table of freqencies of this frequency (meta-frequency?),
  301.              e.g.  'x occurred 5 times in 10 rows, 6 times in 1000 rows,
  302.              7 times in 2 rows'
  303.           3) use the mode of the meta-frequency to determine the /expected/
  304.              frequency for that character
  305.           4) find out how often the character actually meets that goal
  306.           5) the character that best meets its goal is the delimiter
  307.         For performance reasons, the data is evaluated in chunks, so it can
  308.         try and evaluate the smallest portion of the data possible, evaluating
  309.         additional chunks as necessary.
  310.         """
  311.         data = filter(None, data.split('\n'))
  312.         ascii = [ chr(c) for c in range(127) ]
  313.         chunkLength = min(10, len(data))
  314.         iteration = 0
  315.         charFrequency = { }
  316.         modes = { }
  317.         delims = { }
  318.         start = 0
  319.         end = min(chunkLength, len(data))
  320.         while start < len(data):
  321.             iteration += 1
  322.             for line in data[start:end]:
  323.                 for char in ascii:
  324.                     metaFrequency = charFrequency.get(char, { })
  325.                     freq = line.strip().count(char)
  326.                     metaFrequency[freq] = metaFrequency.get(freq, 0) + 1
  327.                     charFrequency[char] = metaFrequency
  328.                 
  329.             
  330.             for char in charFrequency.keys():
  331.                 items = charFrequency[char].items()
  332.                 if len(items) > 1:
  333.                     modes[char] = reduce((lambda a, b: if not a[1] > b[1] or a:
  334. passb), items)
  335.                     items.remove(modes[char])
  336.                     modes[char] = (modes[char][0], modes[char][1] - reduce((lambda a, b: (0, a[1] + b[1])), items)[1])
  337.                     continue
  338.                 None if len(items) == 1 and items[0][0] == 0 else []
  339.                 modes[char] = items[0]
  340.             
  341.             modeList = modes.items()
  342.             total = float(chunkLength * iteration)
  343.             consistency = 1.0
  344.             threshold = 0.90000000000000002
  345.             while len(delims) == 0 and consistency >= threshold:
  346.                 for k, v in modeList:
  347.                     if v[0] > 0 and v[1] > 0:
  348.                         if v[1] / total >= consistency:
  349.                             pass
  350.                         None if delimiters is None or k in delimiters else k in delimiters
  351.                         continue
  352.                 
  353.                 consistency -= 0.01
  354.             if len(delims) == 1:
  355.                 delim = delims.keys()[0]
  356.                 skipinitialspace = data[0].count(delim) == data[0].count('%c ' % delim)
  357.                 return (delim, skipinitialspace)
  358.             
  359.             start = end
  360.             end += chunkLength
  361.         if not delims:
  362.             return ('', 0)
  363.         
  364.         if len(delims) > 1:
  365.             for d in self.preferred:
  366.                 if d in delims.keys():
  367.                     skipinitialspace = data[0].count(d) == data[0].count('%c ' % d)
  368.                     return (d, skipinitialspace)
  369.                     continue
  370.             
  371.         
  372.         delim = delims.keys()[0]
  373.         skipinitialspace = data[0].count(delim) == data[0].count('%c ' % delim)
  374.         return (delim, skipinitialspace)
  375.  
  376.     
  377.     def has_header(self, sample):
  378.         rdr = reader(StringIO(sample), self.sniff(sample))
  379.         header = rdr.next()
  380.         columns = len(header)
  381.         columnTypes = { }
  382.         for i in range(columns):
  383.             columnTypes[i] = None
  384.         
  385.         checked = 0
  386.         for row in rdr:
  387.             if checked > 20:
  388.                 break
  389.             
  390.             checked += 1
  391.             if len(row) != columns:
  392.                 continue
  393.             
  394.             for col in columnTypes.keys():
  395.                 for thisType in [
  396.                     int,
  397.                     long,
  398.                     float,
  399.                     complex]:
  400.                     
  401.                     try:
  402.                         thisType(row[col])
  403.                     continue
  404.                     except (ValueError, OverflowError):
  405.                         continue
  406.                     
  407.  
  408.                 else:
  409.                     thisType = len(row[col])
  410.                 if thisType == long:
  411.                     thisType = int
  412.                 
  413.                 if thisType != columnTypes[col]:
  414.                     if columnTypes[col] is None:
  415.                         columnTypes[col] = thisType
  416.                     else:
  417.                         del columnTypes[col]
  418.                 columnTypes[col] is None
  419.             
  420.         
  421.         hasHeader = 0
  422.         for col, colType in columnTypes.items():
  423.             if type(colType) == type(0):
  424.                 if len(header[col]) != colType:
  425.                     hasHeader += 1
  426.                 else:
  427.                     hasHeader -= 1
  428.             len(header[col]) != colType
  429.             
  430.             try:
  431.                 colType(header[col])
  432.             except (ValueError, TypeError):
  433.                 hasHeader += 1
  434.                 continue
  435.  
  436.             hasHeader -= 1
  437.         
  438.         return hasHeader > 0
  439.  
  440.  
  441.